home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xpaint-2.1.1
/
PaintEvent.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
7KB
|
279 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
#include <X11/IntrinsicP.h>
#include "PaintP.h"
#include "xpaint.h"
typedef void (*func_t)(Widget, void *, XEvent *, OpInfo *);
typedef struct data_s {
Widget w;
func_t func;
void *data;
int mask, flag;
int surfMask;
struct data_s *next;
OpInfo *info;
} data_t;
static data_t *list = NULL;
#if 0
static data_t **widgetEvent(Widget w, data_t *look)
{
static data_t *d[10];
data_t *cur = list;
int n = 0;
while (cur != NULL) {
if (cur->mask == look->mask &&
cur->flag == look->flag &&
cur->func == look->func &&
cur->w == w)
d[n++] = cur;
cur = cur->next;
}
d[n] = NULL;
return n == 0 ? NULL : d;
}
#endif
static void opHandleEvent(Widget w, XtPointer dataArg, XEvent *event, Boolean *junk)
{
data_t *data = (data_t*)dataArg;
int snap;
PaintWidget paint = (PaintWidget)w;
OpInfo *info = data->info;
static Window lastWindow = None;
static Display *lastDisplay = None;
static int lastType;
static int lastX, lastY;
Boolean same;
int zoom;
#if 0
XEvent myEvent;
memcpy(&myEvent, event, sizeof(XEvent));
event = &myEvent;
#endif
/*
** Figure out if there is a snap, either by
** choice or by zooming
*/
if ((info->zoom = GET_ZOOM(paint)) == 0)
info->zoom = 1;
if (info->isFat = ((zoom = GET_ZOOM(paint)) > 1))
snap = GET_ZOOM(paint);
else if (paint->paint.snapOn)
snap = paint->paint.snap;
else
snap = 1;
same = (event->xany.window == lastWindow) &&
(event->xany.display == lastDisplay) &&
(event->xany.type == lastType);
lastWindow = event->xany.window;
lastDisplay = event->xany.display;
lastType = event->xany.type;
/*
** Snap events to the snap
*/
if (event->type == ButtonPress || event->type == ButtonRelease) {
info->realX = event->xbutton.x;
info->realY = event->xbutton.y;
} else if (event->type == MotionNotify) {
info->realX = event->xmotion.x;
info->realY = event->xmotion.y;
}
if (((event->type == ButtonPress) ||
(event->type == ButtonRelease) ||
(event->type == MotionNotify)) && snap > 1) {
switch (event->type) {
case ButtonPress:
case ButtonRelease:
event->xbutton.x = event->xbutton.x -
(event->xbutton.x % snap);
event->xbutton.y = event->xbutton.y -
(event->xbutton.y % snap);
if (same && lastX == event->xbutton.x && lastY == event->xbutton.y)
return;
break;
case MotionNotify:
event->xmotion.x = event->xmotion.x -
(event->xmotion.x % snap);
event->xmotion.y = event->xmotion.y -
(event->xmotion.y % snap);
if (same && lastX == event->xmotion.x && lastY == event->xmotion.y)
return;
break;
}
lastX = event->xmotion.x;
lastY = event->xmotion.y;
} else {
lastX = lastY = -1;
}
if (event->type == MotionNotify) {
info->x = (event->xmotion.x / zoom) + paint->paint.zoomX;
info->y = (event->xmotion.y / zoom) + paint->paint.zoomY;
} else if (event->type == ButtonPress || event->type == ButtonRelease) {
info->x = (event->xbutton.x / zoom) + paint->paint.zoomX;
info->y = (event->xbutton.y / zoom) + paint->paint.zoomY;
}
/*
** In fatbits we can't tell the difference
** between snaping an fat bits.
*/
if (info->isFat) {
info->realX = info->x;
info->realY = info->y;
} else {
info->realX = info->realX + paint->paint.zoomX;
info->realY = info->realY + paint->paint.zoomY;
}
/*
** If this is button down, save it for reference
*/
if (event->type == ButtonPress) {
paint->paint.downX = info->realX;
paint->paint.downY = info->realY;
}
if (paint->paint.paint != None) {
PaintWidget pw = (PaintWidget)paint->paint.paint;
info->base = pw->paint.sourcePixmap;
} else {
info->base = paint->paint.sourcePixmap;
}
if (data->surfMask & opWindow) {
int z = GET_ZOOM(paint) / 2;
if (z != 0) {
if (event->type == MotionNotify) {
event->xmotion.x += z;
event->xmotion.y += z;
} else if (event->type == ButtonPress || event->type == ButtonRelease) {
event->xbutton.x += z;
event->xbutton.y += z;
}
}
info->surface = opWindow;
info->drawable = event->xany.window;
data->func(w, data->data, event, info);
}
if (event->type == MotionNotify) {
event->xmotion.x = info->x;
event->xmotion.y = info->y;
} else if (event->type == ButtonPress || event->type == ButtonRelease) {
event->xbutton.x = info->x;
event->xbutton.y = info->y;
}
if (data->surfMask & opPixmap) {
info->surface = opPixmap;
info->drawable = GET_PIXMAP(paint);
data->func(w, data->data, event, info);
}
}
void OpAddEventHandler(Widget w, int surfMask, int mask, Boolean flag,
void (*func)(Widget,void *, XEvent*, OpInfo *), void *data)
{
PaintWidget paint = (PaintWidget)w;
PaintWidget pp = (PaintWidget)paint->paint.paint;
data_t *new = (data_t *)XtMalloc(sizeof(data_t));
OpInfo *info;
if (new == NULL)
return;
new->w = w;
new->func = func;
new->data = data;
new->mask = mask;
new->flag = flag;
new->surfMask = surfMask;
info = new->info = (OpInfo*)XtMalloc(sizeof(OpInfo));
info->refCount = 1;
info->realX = 0;
info->realY = 0;
/*
** Now build the approprate info structure
*/
if (pp == None) {
/*
** If this is a paint widget, this is easy
*/
info->first_gc = paint->paint.fgc;
info->second_gc = paint->paint.sgc;
info->base_gc = paint->paint.igc;
} else {
/*
** For a fatbits paint widget get paint information
*/
info->first_gc = pp->paint.fgc;
info->second_gc = pp->paint.sgc;
info->base_gc = pp->paint.igc;
}
new->next = list;
list = new;
XtAddEventHandler(w, mask, flag, opHandleEvent, (XtPointer)new);
}
void OpRemoveEventHandler(Widget w, int surfMask, int mask, Boolean flag,
void (*func)(Widget, void *, XEvent*, OpInfo *), void *data)
{
data_t *cur = list;
data_t **prev = &list;
while (cur != NULL) {
if (cur->w == w &&
cur->data == data &&
cur->mask == mask &&
cur->flag == flag &&
cur->surfMask == surfMask &&
cur->func == func)
break;
prev = &cur->next;
cur = cur->next;
}
if (cur == NULL)
return;
XtRemoveEventHandler(w, mask, flag, opHandleEvent, (XtPointer)cur);
*prev = cur->next;
cur->info->refCount--;
if (cur->info->refCount == 0)
XtFree((XtPointer)cur->info);
XtFree((XtPointer)cur);
}